package com.atguigu.lease.web.app.service.impl;

import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.atguigu.lease.common.constant.RedisConstant;
import com.atguigu.lease.common.exception.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.common.utils.JwtUtil;
import com.atguigu.lease.model.entity.UserInfo;
import com.atguigu.lease.model.enums.BaseStatus;
import com.atguigu.lease.web.app.mapper.UserInfoMapper;
import com.atguigu.lease.web.app.service.LoginService;
import com.atguigu.lease.web.app.vo.user.LoginVo;
import com.atguigu.lease.web.app.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private Client client;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Override
    public void sendCode(String phone) throws Exception {
        String key = RedisConstant.APP_LOGIN_PREFIX + phone;

        Boolean aBoolean = redisTemplate.hasKey(key);

        if (aBoolean){
            //还没有过60秒
            new LeaseException(ResultCodeEnum.APP_LOGIN_CODE_EXPIRED);
        }

        String code = "";
        Random random = new Random();
        for (int i = 0; i < 4; ++i){
            code += random.nextInt(10);
        }

        SendSmsRequest sendSmsRequest = new SendSmsRequest();
        sendSmsRequest.setPhoneNumbers(phone);
        sendSmsRequest.setSignName("阿里云短信测试");
        sendSmsRequest.setTemplateCode("SMS_154950909");
        sendSmsRequest.setTemplateParam("{\"code\":\"" + code + "\"}\n");

        System.out.println(code);

        client.sendSms(sendSmsRequest);

        redisTemplate.opsForValue().set(key, code, RedisConstant.APP_LOGIN_CODE_RESEND_TIME_SEC, TimeUnit.SECONDS);
    }

    @Override
    public String login(LoginVo loginVo) {
        //校验一下手机号码和验证码是否为空
        if (loginVo.getPhone() == null){
            throw new LeaseException(ResultCodeEnum.APP_LOGIN_PHONE_EMPTY);
        }

        if (loginVo.getCode() == null){
            throw new LeaseException(ResultCodeEnum.APP_LOGIN_CODE_EMPTY);
        }

        //查询验证码
        String key = RedisConstant.APP_LOGIN_PREFIX + loginVo.getPhone();

        String code = (String)redisTemplate.opsForValue().get(key);

        //看看redis数据库中有没有code（如果没有抛出状态码已过期的异常）
        if (code == null){
            throw new LeaseException(ResultCodeEnum.APP_LOGIN_CODE_EXPIRED);
        }

        //如果redis数据库中的code和前端传递的code不一致，抛出异常
        if (!code.equals(loginVo.getCode())){
            throw new LeaseException(ResultCodeEnum.APP_LOGIN_CODE_ERROR);
        }

        //根据手机号码查询用户的信息
        LambdaQueryWrapper<UserInfo> userInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userInfoLambdaQueryWrapper.eq(UserInfo::getPhone, loginVo.getPhone());

        //查询用户信息（直接调用selectOne就可以）
        UserInfo userInfo = userInfoMapper.selectOne(userInfoLambdaQueryWrapper);

        //判断结果是否为空（如果为空，就说明是一个新用户，新用户是注册，老用户是登录（但需要判断是否被禁用了））

        if (userInfo == null){
            //需要给对象设置属性，手机号码，昵称，账号的状态，密码就不需要（这种登录方式用不到密码）
            UserInfo newUserInfo = new UserInfo();
            newUserInfo.setNickname("用户：" + loginVo.getPhone().substring(7));
            newUserInfo.setPhone(loginVo.getPhone());
            newUserInfo.setStatus(BaseStatus.ENABLE);
            userInfoMapper.insert(newUserInfo);
        }else {
            //如果账号状态被禁用，抛出对应的异常
            if (userInfo.getStatus() == BaseStatus.DISABLE){
                throw new LeaseException(ResultCodeEnum.APP_ACCOUNT_DISABLED_ERROR);
            }
        }

        //查询用户信息（直接调用selectOne就可以）
        UserInfo userInfo1 = userInfoMapper.selectOne(userInfoLambdaQueryWrapper);

        //返回Token（移动端的的username就是手机号码）
        return JwtUtil.createToken(userInfo1.getId(), userInfo1.getPhone());
    }

    @Override
    public UserInfoVo getLoginUserById(Long userId) {
        UserInfo userInfo = userInfoMapper.selectById(userId);
        //接收结果的是一个Vo，不是Info
        UserInfoVo userInfoVo = new UserInfoVo(userInfo.getNickname(), userInfo.getAvatarUrl());

        return userInfoVo;
    }
}
